// 特约商户进件
package wxmch_api

import (
	"context"
	"encoding/json"
	"fmt"
)

// 超级管理员信息
type SubContactInfo struct {
	// 超级管理员姓名
	ContactName string `json:"contact_name"`
	// 超级管理员身份证件号码
	ContactIDNumber string `json:"contact_id_number,omitempty"`
	// 超级管理员微信openid
	Openid string `json:"openid,omitempty"`
	// 联系手机
	MobilePhone string `json:"mobile_phone"`
	// 联系邮箱
	ContactEmail string `json:"contact_email"`
}

// 特约商户营业执照信息
type SubBusinessLicenseInfo struct {
	// 营业执照照片
	LicenseCopy string `json:"license_copy"`
	// 注册号/统一社会信用代码
	LicenseNumber string `json:"license_number"`
	// 商户名称
	MerchantName string `json:"merchant_name"`
	// 个体户经营者/法人姓名
	LegalPerson string `json:"legal_person"`
}

// 登记证书 主体为党政、机关及事业单位/其他组织，必填
type CertificateInfo struct {
	// 登记证书照片
	CertCopy string `json:"cert_copy"`
	// 登记证书类型
	CertType string `json:"cert_type"`
	// 证书号
	CertNumber string `json:"cert_number"`
	// 商户名称
	MerchantName string `json:"merchant_name"`
	// 注册地址
	CompanyAddress string `json:"company_address"`
	// 法人姓名
	LegalPerson string `json:"legal_person"`
	// 有效期限开始日期
	PeriodBegin string `json:"period_begin"`
	// 有效期限结束日期
	PeriodEnd string `json:"period_end"`
}

// 组织机构代码证
type OrganizationInfo struct {
	// 组织机构代码证照片
	OrganizationCopy string `json:"organization_copy"`
	// 组织机构代码
	OrganizationCode string `json:"organization_code"`
	// 组织机构代码证有效期开始日期
	OrgPeriodBegin string `json:"org_period_begin"`
	// 组织机构代码证有效期结束日期
	OrgPeriodEnd string `json:"org_period_end"`
}

// 身份证信息
type SubIDCardInfo struct {
	// 身份证人像面照片
	IDCardCopy string `json:"id_card_copy"`
	// 身份证国徽面照片
	IDCardNational string `json:"id_card_national"`
	// 身份证姓名
	IDCardName string `json:"id_card_name"`
	// 身份证号码
	IDCardNumber string `json:"id_card_number"`
	// 身份证有效期开始时间
	CardPeriodBegin string `json:"card_period_begin"`
	// 身份证有效期结束时间
	CardPeriodEnd string `json:"card_period_end"`
}

// 其他类型证件信息
type SubIDDocInfo struct {
	// 证件照片
	IDDocCopy string `json:"id_doc_copy"`
	// 证件姓名
	IDDocName string `json:"id_doc_name"`
	// 证件号码
	IDDocNumber string `json:"id_doc_number"`
	//  证件有效期开始时间
	DocPeriodBegin string `json:"doc_period_begin"`
	// 证件有效期结束时间
	DocPeriodEnd string `json:"doc_period_end"`
}

// 经营者/法人身份证件
type IdentityInfo struct {
	// 证据类型
	IDDocType string `json:"id_doc_type"`
	// 身份证信息
	IDCardInfo *SubIDCardInfo `json:"id_card_info,omitempty"`
	// 其他类型证件
	IDDocInfo *SubIDDocInfo `json:"id_doc_info,omitempty"`
	//是否为最终受益人
	Owner bool `json:"owner"`
}

// 最终受益人信息
type UboInfo struct {
	// 证件类型
	IDType string `json:"id_type"`
	// 身份证人像面照片
	IDCardCopy string `json:"id_card_copy,omitempty"`
	// 身份证国徽面照片
	IDCardNational string `json:"id_card_national,omitempty"`
	// 证件照片
	IDDocCopy string `json:"id_doc_copy,omitempty"`
	// 受益人姓名
	Name string `json:"name"`
	// 证件号码
	IDNumber string `json:"id_number"`
	// 证件有效期开始时间
	IDPeriodBegin string `json:"id_period_begin"`
	// 证件有效期结束时间
	IDPeriodEnd string `json:"id_period_end"`
}

// 门店场所
type MicroStoreInfo struct {
	// 门店名称
	MicroName string `json:"micro_name"`
	// 门店省市编码
	MicroAddressCode string `json:"micro_address_code"`
	// 门店地址
	MicroAddress string `json:"micro_address"`
	// 门店门头照片
	StoreEntrancePic string `json:"store_entrance_pic"`
	// 门店店内环境照片
	MicroIndoorCopy string `json:"micro_indoor_copy"`
	// 门店经度
	StoreLongitude string `json:"store_longitude"`
	// 门店纬度
	StoreLatitude string `json:"store_latitude"`
}

// 流动经营/便民服务
type MicroMobileInfo struct {
	// 经营/服务名称
	MicroMobileName string `json:"micro_mobile_name"`
	// 经营/服务所在地省市
	MicroMobileCity string `json:"micro_mobile_city"`
	// 经营/服务所在地（不含省市]
	MicroMobileAddress string `json:"micro_mobile_address"`
	// 经营服务现场照片
	MicroMobilePics []string `json:"micro_mobile_pics"`
}

// 线上商品/服务交易
type MicroOnlineInfo struct {
	// 线上店铺名称
	MicroOnlineStore string `json:"micro_online_store"`
	// 电商平台名称
	MicroEcName string `json:"micro_ec_name"`
	// 店铺二维码
	MicroQrcode string `json:"micro_qrcode"`
	// 店铺链接
	MicroLink string `json:"micro_link"`
}

// 小微证明材料
type MicroBizInfo struct {
	// 微信经营类型
	MicroBizType string `json:"micro_biz_type"`
	// 门店场所
	MicroStoreInfo *MicroStoreInfo `json:"micro_store_info"`
	// 流动经营/便民服务
	MicroMobileInfo *MicroMobileInfo `json:"micro_mobile_info"`
	// 线上商品服务交易
	MicroOnlineInfo *MicroOnlineInfo `json:"micro_online_info"`
}

// 主体资料
type SubjectInfo struct {
	// 主体类型
	SubjectType string `json:"subject_type"`
	// 营业执照
	BusinessLicenseInfo *SubBusinessLicenseInfo `json:"business_license_info,omitempty"`
	// 登记证书
	CertificateInfo *CertificateInfo `json:"certificate_info,omitempty"`
	// 组织机构代码证
	OrganizationInfo *OrganizationInfo `json:"organization_info,omitempty"`
	// 单位证明函照片
	CertificateLetterCopy string `json:"certificate_letter_copy,omitempty"`
	// 经营者/法人身份证件
	IdentityInfo *IdentityInfo `json:"identity_info"`
	// 最终受益人信息
	UboInfo *UboInfo `json:"ubo_info,omitempty"`
	// 小微辅助证明材料
	MicroBizInfo *MicroBizInfo `json:"micro_biz_info,omitempty"`
}

// 线下门店信息
type BizStoreInfo struct {
	// 门店名称
	BizStoreName string `json:"biz_store_name"`
	// 门店省市编码
	BizAddressCode string `json:"biz_address_code"`
	// 门店地址
	BizStoreAddress string `json:"biz_store_address"`
	// 门店门头照片
	StoreEntrancePic []string `json:"store_entrance_pic"`
	// 门店店内环境照片
	IndoorPic []string `json:"indoor_pic"`
	// 先下场所对应商家appid
	BizSubAppid string `json:"biz_sub_appid,omitempty"`
}

// 公众号信息
type MpInfo struct {
	// 服务商公众号APPID
	MpAppid string `json:"mp_appid,omitempty"`
	// 商家公众号 appid
	MpSubAppid string `json:"mp_sub_appid,omitempty"`
	// 公众号页面截图
	MpPics []string `json:"mp_pics,omitempty"`
}

// 小程序场景
type MiniProgramInfo struct {
	// 服务商小程序APPID
	MiniProgramAppid string `json:"mini_program_appid,omitempty"`
	// 商家小程序 appid
	MiniProgramSubAppid string `json:"mini_program_sub_appid,omitempty"`
	// 小程序截图
	MiniProgramPics []string `json:"mini_program_pics,omitempty"`
}

// app 场景
type AppInfo struct {
	// 服务商应用APPID
	AppAppid string `json:"app_appid,omitempty"`
	// 商家应用 appid
	AppSubAppid string `json:"app_sub_appid,omitempty"`
	// 应用页面截图
	AppPics []string `json:"app_pics"`
}

// 互联网场景
type WebInfo struct {
	// 互联网网站域名
	Domain string `json:"domain"`
	// 网站授权函
	WebAuthorisation string `json:"web_authorisation,omitempty"`
	// 应用页面截图
	WebAppID string `json:"web_app_id,omitempty"`
}

// 企业微信场景
type WeworkInfo struct {
	// 商家企业微信corpid
	SubCorpID string `json:"sub_corp_id"`
	// 企业微信页截图
	WeworkPics []string `json:"wework_pics"`
}

// 经营场景
type SalesInfo struct {
	// 经营场景类型
	SalesScenesType []string `json:"sales_scenes_type"`
	// 线下门店场景
	BizStoreInfo *BizStoreInfo `json:"biz_store_info,omitempty"`
	// 公众号场景
	MpInfo *MpInfo `json:"mp_info,omitempty"`
	// 小程序场景
	MiniProgramInfo *MiniProgramInfo `json:"mini_program_info,omitempty"`
	// APP 场景
	AppInfo *AppInfo `json:"app_info,omitempty"`
	// 互联网场景
	WebInfo *WebInfo `json:"web_info,omitempty"`
	// 企业微信场景
	WeworkInfo *WeworkInfo `json:"wework_info,omitempty"`
}

// 经营资料
type BusinessInfo struct {
	// 商户简称
	MerchantShortname string `json:"merchant_shortname"`
	// 客服电话
	ServicePhone string `json:"service_phone"`
	// salesInfo
	SalesInfo *SalesInfo `json:"sales_info"`
}

// 结算规则
type SettlementInfo struct {
	//    入驻结算规则ID
	SettlementID string `json:"settlement_id"`
	// 所属行业
	QualificationType string `json:"qualification_type"`
	// 特殊资质图片
	Qualifications []string `json:"qualifications,omitempty"`
	// 优惠费率活动ID
	ActivitiesID string `json:"activities_id,omitempty"`
	// 优惠费率活动值
	ActivitiesRate string `json:"activities_rate,omitempty"`
	// 优惠费率活动补充材料
	ActivitiesAdditions []string `json:"activities_additions,omitempty"`
}

// 结算银行账户
type BankAccountInfo struct {
	// 账户类型
	BankAccountType string `json:"bank_account_type"`
	// 开户银行
	AccountBank string `json:"account_bank"`
	// 开户名称
	AccountName string `json:"account_name"`
	// 开户银行省市编码
	BankAddressCode string `json:"bank_address_code"`
	// 开户银行联行号
	BankBranchID string `json:"bank_branch_id,omitempty"`
	// 开户银行全称 （含支行）
	BankName string `json:"bank_name,omitempty"`
	// 银行帐号
	AccountNumber string `json:"account_number"`
}

// 补充材料
type AdditionInfo struct {
	// 法人开户承诺函
	LegalPersonCommitment string `json:"legal_person_commitment,omitempty"`
	// 法人开户意愿视频
	LegalPersonVideo string `json:"legal_person_video,omitempty"`
	// 补充材料
	BusinessAdditionPics []string `json:"business_addition_pics,omitempty"`
	// 补充说明
	BusinessAdditionMsg string `json:"business_addition_msg,omitempty"`
}

// 特约商户进件申请参数
type SubMchApplymentRequest struct {
	// 业务申请编号
	BusinessCode string `json:"business_code"`
	// 超级管理员信息
	ContactInfo *SubContactInfo `json:"contact_info"`
	// 主体资料信息
	SubjectInfo *SubjectInfo `json:"subject_info"`
	// 经营资料
	BusinessInfo *BusinessInfo `json:"business_info"`
	// 结算规则
	SettlementInfo *SettlementInfo `json:"settlement_info"`
	// 结算银行账户
	BankAccountInfo *BankAccountInfo `json:"bank_account_info,omitempty"`
	// 补充材料
	AdditionInfo *AdditionInfo `json:"addition_info,omitempty"`
}

type SubMchApplymentResponse struct {
	// 微信支付申请单号
	ApplymentID int64 `json:"applyment_id"`
}

func (c *MerchantApiClient) SubMchApplymentSubmit(ctx context.Context, req SubMchApplymentRequest) (*SubMchApplymentResponse, error) {
	pubKey := c.getPlatformPublicKey()
	// 超级管理员信息加密
	req.ContactInfo.ContactName = encryptCiphertext(req.ContactInfo.ContactName, pubKey)
	req.ContactInfo.ContactIDNumber = encryptCiphertext(req.ContactInfo.ContactIDNumber, pubKey)
	req.ContactInfo.Openid = encryptCiphertext(req.ContactInfo.Openid, pubKey)
	req.ContactInfo.MobilePhone = encryptCiphertext(req.ContactInfo.MobilePhone, pubKey)
	req.ContactInfo.ContactEmail = encryptCiphertext(req.ContactInfo.ContactEmail, pubKey)
	// 主体资料加密
	if req.SubjectInfo.IdentityInfo.IDCardInfo != nil {
		req.SubjectInfo.IdentityInfo.IDCardInfo.IDCardName = encryptCiphertext(req.SubjectInfo.IdentityInfo.IDCardInfo.IDCardName, pubKey)
		req.SubjectInfo.IdentityInfo.IDCardInfo.IDCardNumber = encryptCiphertext(req.SubjectInfo.IdentityInfo.IDCardInfo.IDCardNumber, pubKey)
	}
	if req.SubjectInfo.IdentityInfo.IDDocInfo != nil {
		req.SubjectInfo.IdentityInfo.IDDocInfo.IDDocName = encryptCiphertext(req.SubjectInfo.IdentityInfo.IDDocInfo.IDDocName, pubKey)
		req.SubjectInfo.IdentityInfo.IDDocInfo.IDDocNumber = encryptCiphertext(req.SubjectInfo.IdentityInfo.IDDocInfo.IDDocNumber, pubKey)
	}
	if req.SubjectInfo.UboInfo != nil {
		req.SubjectInfo.UboInfo.Name = encryptCiphertext(req.SubjectInfo.UboInfo.Name, pubKey)
		req.SubjectInfo.UboInfo.IDNumber = encryptCiphertext(req.SubjectInfo.UboInfo.IDNumber, pubKey)
	}
	// 结算银行账户信息加密
	if req.BankAccountInfo != nil {
		req.BankAccountInfo.AccountName = encryptCiphertext(req.BankAccountInfo.AccountName, pubKey)
		req.BankAccountInfo.AccountNumber = encryptCiphertext(req.BankAccountInfo.AccountNumber, pubKey)
	}
	body, _ := json.Marshal(req)
	res, err := c.doRequestAndVerifySignature(ctx, "POST", "/v3/applyment4sub/applyment/", nil, body)
	if err != nil {
		return nil, err
	}
	resp := &SubMchApplymentResponse{}
	err = json.Unmarshal(res, &resp)
	return resp, nil
}

// 通过业务申请编号查询申请状态请求
type SubMchApplymentQueryByOutRequestNoRequest struct {
	BusinessCode string `json:"business_code"`
}

// 通过申请单号查询申请状态请求
type SubMchApplymentQueryByApplymentIDRequest struct {
	ApplymentID int64 `json:"applyment_id"`
}

type SubAuditDetail struct {
	// 字段名
	Field string `json:"field"`
	// 字段名称
	FieldName string `json:"field_name"`
	// 驳回原因
	RejectReason string `json:"reject_reason"`
}

type SubMchApplymentQueryResponse struct {
	// 业务申请编号
	BusinessCode string `json:"business_code"`
	// 微信支付申请单号
	ApplymentID int64 `json:"applyment_id"`
	// 特约商户号
	SubMchid string `json:"sub_mchid"`
	// 超级管理员签约链接
	SignUrl string `json:"sign_url"`
	// 申请单状态
	ApplymentState string `json:"applyment_state"`
	// 申请状态描述
	ApplymentStateMsg string `json:"applyment_state_msg"`
	// 驳回原因详情
	AuditDetail []*SubAuditDetail `json:"audit_detail"`
}

// 通过业务申请编号查询申请状态
func (c *MerchantApiClient) SubMchApplymentQueryByOutRequestNo(ctx context.Context, req SubMchApplymentQueryByOutRequestNoRequest) (*SubMchApplymentQueryResponse, error) {
	url := fmt.Sprintf("/v3/applyment4sub/applyment/business_code/%s", req.BusinessCode)
	res, err := c.doRequestAndVerifySignature(ctx, "GET", url, nil, nil)
	if err != nil {
		return nil, err
	}
	resp := &SubMchApplymentQueryResponse{}
	err = json.Unmarshal(res, &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// 通过申请单号查询申请状态
func (c *MerchantApiClient) SubMchApplymentQueryByID(ctx context.Context, req SubMchApplymentQueryByApplymentIDRequest) (*SubMchApplymentQueryResponse, error) {
	url := fmt.Sprintf("/v3/applyment4sub/applyment/applyment_id/%d", req.ApplymentID)
	res, err := c.doRequestAndVerifySignature(ctx, "GET", url, nil, nil)
	if err != nil {
		return nil, err
	}
	resp := &SubMchApplymentQueryResponse{}
	err = json.Unmarshal(res, &resp)
	return resp, err
}

// 修改结算账号请求
type SubMchModifySettlementRequest struct {
	// 特约商户号
	SubMchid string `json:"sub_mchid"`
	// 账户类型
	AccountType string `json:"account_type"`
	// 开户银行
	AccountBank string `json:"account_bank"`
	// 开户银行省市编码
	BankAddressCode string `json:"bank_address_code"`
	// 开户银行全称（含支行）
	BankName string `json:"bank_name,omitempty"`
	// 开户银行联行号
	BankBranchID string `json:"bank_branch_id,omitempty"`
	// 银行账号
	AccountNumber string `json:"account_number"`
}

// 修改结算账号
func (c *MerchantApiClient) SubMchSettlementModify(ctx context.Context, req SubMchModifySettlementRequest) error {
	// pubKey
	pubKey := c.getPlatformPublicKey()
	req.AccountNumber = encryptCiphertext(req.AccountNumber, pubKey)
	url := fmt.Sprintf("/v3/apply4sub/sub_merchants/%s/modify-settlement", req.SubMchid)
	body, err := json.Marshal(req)
	if err != nil {
		return err
	}
	_, err = c.doRequestAndVerifySignature(ctx, "POST", url, nil, body)
	return err
}

// 查询结算账号请求
type SubMchSettlementQueryRequest struct {
	// 特约商户号
	SubMchid string `json:"sub_mchid"`
}

// 查询结算账号结果
type SubMchSettlementQueryResponse struct {
	// 账户类型
	AccountType string `json:"account_type"`
	// 开户银行
	AccountBank string `json:"account_bank"`
	// 开户银行全称（含支行]
	BankName string `json:"bank_name"`
	// 开户银行联行号
	BankBranchID string `json:"bank_branch_id"`
	// 银行账号（掩码）
	AccountNumber string `json:"account_number"`
	// 汇款验证结果
	VerifyResult string `json:"verify_result"`
}

// 查询结算账号
func (c *MerchantApiClient) SubMchSettlementQuery(ctx context.Context, req SubMchSettlementQueryRequest) (*SubMchSettlementQueryResponse, error) {
	url := fmt.Sprintf("/v3/apply4sub/sub_merchants/%s/settlement", req.SubMchid)
	res, err := c.doRequestAndVerifySignature(ctx, "GET", url, nil, nil)
	if err != nil {
		return nil, err
	}
	resp := &SubMchSettlementQueryResponse{}
	err = json.Unmarshal(res, resp)
	return resp, err
}
